<!DOCTYPE html>
<html lang="en">

<head>
	<meta charset="UTF-8">
	<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
	<meta name="keywords" content="微服务,DNS" />
	<meta name="description" content="微服务架构中基于DNS的服务注册与发现" />
	<!-- 网页标签标题 -->
	<title>微服务架构中基于DNS的服务注册与发现</title>
	<link rel="shortcut icon" href="https://img.alicdn.com/tfs/TB1hgJpHAPoK1RjSZKbXXX1IXXa-64-64.png"/>
	<link rel="stylesheet" href="/build/blogDetail.css" />
</head>
<body>
	<div id="root"><div class="blog-detail-page" data-reactroot="" data-reactid="1" data-react-checksum="1330331647"><header class="header-container header-container-normal" data-reactid="2"><div class="header-body" data-reactid="3"><a href="/zh-cn/index.html" data-reactid="4"><img class="logo" src="/img/nacos_colorful.png" data-reactid="5"/></a><div class="search search-normal" data-reactid="6"><span class="icon-search" data-reactid="7"></span></div><span class="language-switch language-switch-normal" data-reactid="8">En</span><div class="header-menu" data-reactid="9"><img class="header-menu-toggle" src="/img/menu_gray.png" data-reactid="10"/><ul data-reactid="11"><li class="menu-item menu-item-normal" data-reactid="12"><a href="/zh-cn/index.html" data-reactid="13">首页</a></li><li class="menu-item menu-item-normal" data-reactid="14"><a href="/zh-cn/docs/what-is-nacos.html" data-reactid="15">文档</a></li><li class="menu-item menu-item-normal menu-item-normal-active" data-reactid="16"><a href="/zh-cn/blog/index.html" data-reactid="17">博客</a></li><li class="menu-item menu-item-normal" data-reactid="18"><a href="/zh-cn/community/index.html" data-reactid="19">社区</a></li><li class="menu-item menu-item-normal" data-reactid="20"><a href="https://cn.aliyun.com/product/aliware/mse?spm=nacos-website.topbar.0.0.0" data-reactid="21">企业版Nacos</a><img class="menu-img" src="https://img.alicdn.com/tfs/TB1esl_m.T1gK0jSZFrXXcNCXXa-200-200.png" data-reactid="22"/></li><li class="menu-item menu-item-normal" data-reactid="23"><a href="https://job.alibaba.com/zhaopin/position_detail.htm?trace=qrcode_share&amp;positionCode=GP633620" data-reactid="24">招贤纳士</a><img class="menu-img" src="https://img.alicdn.com/tfs/TB1esl_m.T1gK0jSZFrXXcNCXXa-200-200.png" data-reactid="25"/></li><li class="menu-item menu-item-normal" data-reactid="26"><a href="http://console.nacos.io/nacos/index.html" data-reactid="27">控制台样例</a></li></ul></div></div></header><section class="blog-content markdown-body" data-reactid="28"><h1>微服务架构中基于DNS的服务注册与发现</h1>
<p>当前，微服务架构已经成为企业尤其是互联网企业技术选型的一个重要参考。微服务架构中涉及到很多模块，本文将重点介绍微服务架构的服务注册与发现以及如何基于DNS做服务发现。最后，简单介绍下阿里巴巴内部是如何基于DNS做服务发现的。</p>
<h2>服务注册与发现</h2>
<p>微服务体系中，服务注册与服务发现是两个最核心的模块。服务A调用服务B时，需要通过服务发现模块找到服务B的IP和端口列表，而服务B的实例在启动时需要把提供服务的IP和端口注册到服务注册中心。一个典型的结构如下图：</p>
<p><img src="https://cdn.yuque.com/lark/0/2018/png/7601/1525185623334-8fbf69bb-00df-4202-a951-c1ee9caace88.png" alt="image.png | left | 733x470"></p>
<h3>服务注册</h3>
<p>目前，流行的注册中心比较多，常见的有zookeeper、ectd、consul、eureka等。服务注册通常有三种：自注册、第三方注册、注册中心主动同步。</p>
<ul>
<li>自注册
自注册，顾名思义，就是服务提供方在启动服务时自己把提供服务的IP和端口发送到注册中心，并通过心跳方式维持健康状态；服务下线时，自己把相应的数据删除。典型的像使用eureka客户端发布微服务。</li>
<li>第三方注册
第三方注册是指，存在一个第三方的系统负责在服务启动或停止时向注册中心增加或删除服务数据。典型的用法是devops系统或容器调度系统主动调注册中心接口注册服务；</li>
<li>注册中心主动同步
与第三方注册方式类似，主动注册方式是指注册中心和调度或发布系统打通，主动同步最新的服务IP列表；一个例子是kubernetes体系中，coredns订阅api server数据。</li>
</ul>
<h3>服务发现</h3>
<p>在真正发起服务调用前，调用方需要从注册中心拿到相应服务可用的IP和端口列表，即服务发现。服务发现从对应用的侵入性上可以分为两大类：</p>
<ul>
<li>SDK-Based
这类的服务发现方式，需要调用方依赖相应的SDK，显式调用SDK代码才可以实现服务调用，即对业务有侵入性，典型例子如eureka、zookeeper等。</li>
<li>DNS-Based
DNS本身是一种域名解析系统，可以满足简单的服务发现场景，如双方约定好端口、序列化协议等等。但是，这远远不能满足真正的微服务场景需求。近几年，基于dns的服务发现渐渐被业界提了出来。后面将重点介绍基于DNS的服务发现及阿里巴巴的实践。</li>
</ul>
<h2>基于DNS的服务发现</h2>
<p>DNS协议是目前最为通用的协议之一，几乎所有操作系统都会有DNS客户端实现。所以，其天然具有跨语言特性。这也是快速接入微服务体系最快的一个方式。要基于DNS做服务发现，首先注册中心的数据应该可以以DNS的数据格式暴露出来。让任何系统的DNS 客户端都可以通过DNS协议获取服务列表。</p>
<p>基于DNS的服务发现方式，大致可以归结两类：</p>
<h3>独立DNS服务器</h3>
<p>独立DNS Server模式的基本架构如下图：</p>
<p><img src="https://cdn.yuque.com/lark/0/2018/png/7601/1525185653048-094f815d-47af-409e-ac21-6662e20e76f4.png" alt="image.png | left | 747x469"></p>
<p>如上图所示，这种架构中，需要独立的DNS服务器。DNS服务器从注册中心获取所有已注册的服务及对应的IP端口列表。调用方Service A 通过DNS查询某个服务下的IP列表，然后发起调用。</p>
<p>这种类型的服务发现方式优缺点分别如下：</p>
<ul>
<li>优点
<ul>
<li>集中的DNS服务器，便于升级维护</li>
</ul>
</li>
<li>缺点
<ul>
<li>对DNS服务器性能要求高</li>
<li>这种情况下一般需要LVS设备为DNS服务器集群做请求转发，存在单点问题</li>
</ul>
</li>
</ul>
<h3>DNS Filter</h3>
<p>DNS Filter模式我们定义为把DNS服务器集成到服务调用方机器或容器里，如下图所示：</p>
<p><img src="https://cdn.yuque.com/lark/0/2018/png/7601/1525185676597-acaebac3-2b65-48a3-bdbf-7d27af7f1038.png" alt="image.png | left | 747x469"></p>
<p>这种模式中，首先要保证ServiceA的DNS查询都被拦截到本机的DNS服务器上（127.0.0.1:53），在获取到服务的IP列表后发起调用。由于这种方式把DNS服务器前置到实际调用的机器上，所以它解决了独立DNS服务器模式的单点问题，完全P2P的模式。但由于需要在应用机器上安装DNS服务器，其维护和升级成本较前者高一些。</p>
<h3>阿里基于DNS的服务发现实践</h3>
<p>阿里巴巴早在2014年就开始了基于DNS做服务发现的尝试了，现在已经形成了较为成熟的模式。阿里内部以VIPServer作为注册中心，并开发了DNS Filter，部署在应用容器内。目前已经有超过20w个机器或容器上安装了DNS Filter，支持了几乎所有REST服务发现。</p>
<h4>注册中心 VIPServer</h4>
<p>VIPServer是阿里中间件软负载团队自研的服务注册中心，按照第一章的分类，VIPServer同时支持三种模式的服务注册，并且均有相当规模的应用。除此之外，VIPServer具备如下特性：</p>
<ul>
<li>主动与被动健康检查
VIPServer同时支持主动与被动健康检查。主动健康检查是指VIPserver服务端主动定期发送健康检查探测包，探测服务提供方是否可以正常提供服务。用户可以配置多种健康检查方式，自定义探测端口和探测URL（HTTP）。主动探测的好处在于服务提供方不用做任何改动即可快融入微服务架构。被动健康检查则是指服务提供方主动注册自己的IP、端口和服务名等信息，并通过心跳方式保持活性。</li>
<li>多种负载均衡策略
同时，VIPServer支持多种负载均衡策略，包括权重、同机房、同地域、同环境等等，是阿里异地多活项目的核心系统之一。后面会有专门的文章介绍如何基于VIPServer实现异地多活，这里不再赘述。</li>
<li>多重容灾保护策略
VIPServer提供了多种容灾保护策略，可以有效减少人为或者底层系统（网络等）异常带来的影响。这些容灾保护包括：
<ul>
<li>客户端缓存，即使VIPServer服务端挂掉也不影响应用的正常调用；</li>
<li>服务端保护阈值，有效防止应用因压力过大而发生雪崩；</li>
<li>客户端容灾目录，提供人工干预服务IP列表的能力；</li>
<li>客户端空列表保护，有效防止人为误删IP列表操作或VIPServer服务端异常</li>
</ul>
</li>
</ul>
<h4>DNS-F客户端</h4>
<p>出于性能的考虑，我们采用了第二种DNS Filter的服务发现模式。为此，我们单独开发了DNS-F客户端，DNS-F客户端跟应用部署在同一个主机或容器内。其工作原理如下图所示：</p>
<p><img src="https://cdn.yuque.com/lark/0/2018/png/7601/1525185700084-16f2c073-0c2b-49c0-b85b-ce2ca1163326.png" alt="image.png | left | 716x392"></p>
<ul>
<li>首先，应用ServiceA通过DNS查询获取到ServiceB的可用IP列表</li>
<li>DNS-F会拦截到ServiceA的查询请求，判断自己是否该查询的答案，如果有（服务已在VIPServer中注册）则直接返回IP列表；</li>
<li>如果查询的服务在VIPServer中没有注册，DNS-F把DNS查询转发给系统的nameserver，由真正的DNS系统解析；</li>
</ul>
<h2>总结</h2>
<p>本文介绍了微服务架构中如何基于DNS做服务发现。首先，介绍了服务法注册与发现的概念、服务注册与发现的几种方式及其优缺点；然后，介绍基于DNS的服务发现的两种方式及其优缺点；最后，介绍了阿里巴巴基于DNS做服务发现的实践，主要是基于自研的软负载系统VIPServer。基于DNS的服务发现要解决的问题远不止本文描述的这些，敬请期待后续系列文章（：。</p>
</section><footer class="footer-container" data-reactid="29"><div class="footer-body" data-reactid="30"><img src="/img/nacos_gray.png" data-reactid="31"/><div class="cols-container" data-reactid="32"><div class="col col-12" data-reactid="33"><h3 data-reactid="34">愿景</h3><p data-reactid="35">Nacos 通过提供简单易用的动态服务发现、服务配置、服务共享与管理等服务基础设施，帮助用户在云原生时代，在私有云、混合云或者公有云等所有云环境中，更好的构建、交付、管理自己的微服务平台，更快的复用和组合业务服务，更快的交付商业创新的价值，从而为用户赢得市场。</p></div><div class="col col-6" data-reactid="36"><dl data-reactid="37"><dt data-reactid="38">文档</dt><dd data-reactid="39"><a href="/zh-cn/docs/what-is-nacos.html" target="_self" data-reactid="40">概览</a></dd><dd data-reactid="41"><a href="/zh-cn/docs/quick-start.html" target="_self" data-reactid="42">快速开始</a></dd><dd data-reactid="43"><a href="/zh-cn/docs/contributing.html" target="_self" data-reactid="44">开发者指南</a></dd></dl></div><div class="col col-6" data-reactid="45"><dl data-reactid="46"><dt data-reactid="47">资源</dt><dd data-reactid="48"><a href="/zh-cn/community/index.html" target="_self" data-reactid="49">社区</a></dd><dd data-reactid="50"><a href="https://www.aliyun.com/product/acm?source_type=nacos_pc_20181219" target="_self" data-reactid="51">云服务 ACM</a></dd><dd data-reactid="52"><a href="https://www.aliyun.com/product/edas?source_type=nacos_pc_20181219" target="_self" data-reactid="53">云服务 EDAS</a></dd><dd data-reactid="54"><a href="https://www.aliyun.com/product/ahas?source_type=nacos_pc_20190225" target="_self" data-reactid="55">云服务 AHAS</a></dd></dl></div></div><div class="copyright" data-reactid="56"><span data-reactid="57">@ 2018 The Nacos Authors | An Alibaba Middleware (Aliware) Project</span></div></div></footer></div></div>
	<script src="https://f.alicdn.com/react/15.4.1/react-with-addons.min.js"></script>
	<script src="https://f.alicdn.com/react/15.4.1/react-dom.min.js"></script>
	<script>
		window.rootPath = '';
  </script>
	<script src="/build/blogDetail.js"></script>
</body>
</html>